package com.lawyer.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.collections.map.ListOrderedMap;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.google.common.base.Joiner;
import com.lawyer.entity.Documents;
import com.lawyer.entity.Lawyer;
import com.lawyer.entity.LawyerCaseInfo;
import com.lawyer.entity.LawyerLabel;
import com.lawyer.entity.LawyerMicroInfo;
import com.lawyer.entity.MoneyFlows;
import com.lawyer.entity.Withdrawal;
import com.lawyer.model.CertificationRequest;
import com.lawyer.model.Message;
import com.lawyer.model.MessageConstant;
import com.lawyer.model.MyTaskReq;
import com.lawyer.model.UpudateLawyerReq;
import com.lawyer.repository.DocumentsRepository;
import com.lawyer.repository.LawyerCaseInfoRepository;
import com.lawyer.repository.LawyerLabelRepository;
import com.lawyer.repository.LawyerRepository;
import com.lawyer.repository.MoneyFlowsRepository;
import com.lawyer.repository.UserLawyerRepository;
import com.lawyer.repository.UserRepository;
import com.lawyer.repository.WithdrawalRepository;
import com.lawyer.service.CaseInfoService;
import com.lawyer.service.FileUpLoadService;
import com.lawyer.service.LawyerService;
import com.lawyer.uitls.BeanUtils;
import com.lawyer.uitls.DateUtils;

@RestController
@RequestMapping(value = "/lawyer")
@Api(tags = "律师相关接口")
@SuppressWarnings("all")
public class LawyerController {

	protected final Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private CaseInfoService caseInfoService;
	@Autowired
	private LawyerService lawyerService;

	@Autowired
	private LawyerRepository lawyerRepository;

	@Autowired
	private UserRepository userRepository;
	@Autowired
	private MoneyFlowsRepository moneyFlowsRepository;

	@Autowired
	private UserLawyerRepository userLawyerRepository;

	@Autowired
	private DocumentsRepository documentsRepository;

	@Autowired
	private LawyerCaseInfoRepository lawyerCaseInfoRepository;

	@Autowired
	private LawyerLabelRepository lawyerLabelRepository;

	@Autowired
	private EntityManager entityManager;
	@Autowired
	private FileUpLoadService fileUpLoadService;
	
	@Autowired
	private WithdrawalRepository withdrawalRepository;
	

	@ApiOperation(httpMethod = "GET", value = "律师详情", notes = "律师详情")
	@RequestMapping(value = "/info", method = RequestMethod.GET)
	public HttpEntity<?> info(String lawyerId,String userId) {
		Message msg = new Message();
		if (StringUtils.isEmpty(userId)) {
			msg.setCode(MessageConstant.FAILED_CODE);
			msg.setMessage("UserId不能为空");
			return new ResponseEntity<>(msg, HttpStatus.OK);
		}

		msg = lawyerService.queryLawyerInfo(lawyerId,userId);

		return new ResponseEntity<>(msg, HttpStatus.OK);
	}

	@ApiOperation(httpMethod = "GET", value = "推荐律师列表", notes = "推荐律师列表")
	@RequestMapping(value = "/recommend", method = RequestMethod.GET)
	public HttpEntity<?> recommend() {
		Message msg = lawyerService.findByRecommend();
		return new ResponseEntity<>(msg, HttpStatus.OK);
	}

	@ApiOperation(httpMethod = "GET", value = "我的钱包", notes = "我的钱包")
	@ApiImplicitParams({ @ApiImplicitParam(name = "page", dataType = "integer", paramType = "query", value = "第几页"),
			@ApiImplicitParam(name = "size", dataType = "integer", paramType = "query", value = "分页条数") })
	@RequestMapping(value = "/myWallet", method = RequestMethod.GET)
	public HttpEntity<?> myWallet(@PageableDefault(page = 0, sort = { "createdDate" }, direction = Sort.Direction.DESC) Pageable pageable, @RequestParam String lawyerId) {
		Message msg = new Message();
		try {
			if (StringUtils.isNotEmpty(lawyerId)) {
				Map<String, Object> resultMap = ListOrderedMap.decorate(new HashMap<String, Object>());

				Lawyer lawyer = lawyerRepository.findOne(lawyerId);
				resultMap.put("balance", lawyer.getBalance());

				Page<MoneyFlows> page = moneyFlowsRepository.findByUserId(lawyerId, pageable);
				resultMap.put("balanceInfoPage", page);

				msg.setData(resultMap);

			}

		} catch (Exception e) {
			e.printStackTrace();
			msg.setCode(MessageConstant.FAILED_CODE);
			msg.setMessage(MessageConstant.FAILED_MSG);
		}

		return new ResponseEntity<>(msg, HttpStatus.OK);
	}

	@ApiOperation(httpMethod = "GET", value = "我的任务", notes = "我的任务")
	@RequestMapping(value = "/myTask", method = RequestMethod.GET)
	@ApiImplicitParams({ @ApiImplicitParam(name = "page", dataType = "integer", paramType = "query", value = "第几页"),
			@ApiImplicitParam(name = "size", dataType = "integer", paramType = "query", value = "分页条数") })
	public HttpEntity<?> myTask(MyTaskReq req, @PageableDefault(page = 0, sort = { "createdDate" }, direction = Sort.Direction.DESC) Pageable pageable) {
		Message msg = new Message();

		// criteriaBuilder用于构建CriteriaQuery的构建器对象
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();

		// criteriaQuery包含查询语句的各个部分，如where、max、sum、groupBy、orderBy等
		CriteriaQuery<Documents> criteriaQuery = criteriaBuilder.createQuery(Documents.class);

		// 获取查询实例的属性，select * from User
		Root<Documents> root = criteriaQuery.from(Documents.class);
		
		criteriaQuery.orderBy(criteriaBuilder.desc(root.get("createdDate")));
		
		// 查询条件
		List<Predicate> predicates = new ArrayList<>();
		// 日期（范围）
		if (StringUtils.isNotEmpty(req.getStartDate())) {
			Date begin = DateUtils.getDayBeginOrEndTime(req.getStartDate(), "begin");

			predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createdDate"), begin));
		}

		if (StringUtils.isNotEmpty(req.getEndDate())) {
			Date end = DateUtils.getDayBeginOrEndTime(req.getEndDate(), "end");

			predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("createdDate"), end));
		}

		if (req.getStatus() != null) {
			predicates.add(criteriaBuilder.equal(root.get("status"), req.getStatus()));
		}

		criteriaQuery.where(criteriaBuilder.equal(root.get("acceptLawyerId"), req.getLawyerId()));

		// 将所有条件用 and 联合起来
		if (!CollectionUtils.isEmpty(predicates)) {
			criteriaQuery.where(criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])));
		}

		List<Documents> counts = entityManager.createQuery(criteriaQuery).getResultList();
		TypedQuery<Documents> createQuery = entityManager.createQuery(criteriaQuery);
		createQuery.setFirstResult(pageable.getPageNumber() * pageable.getPageSize());
		createQuery.setMaxResults(pageable.getPageSize());

		Page page = new PageImpl<Documents>(createQuery.getResultList(), pageable, counts.size());

		msg.setData(page);

		return new ResponseEntity<>(msg, HttpStatus.OK);
	}

	@ApiOperation(httpMethod = "POST", value = "律师添加经典案例", notes = "律师添加经典案例")
	@RequestMapping(value = "/classics", method = RequestMethod.POST)
	public HttpEntity<?> classics(@RequestBody LawyerCaseInfo caseInfo) {
		Message msg = new Message();
		if (StringUtils.isNotEmpty(caseInfo.getLawyerId())) {
			Lawyer lawyer = lawyerRepository.findOne(caseInfo.getLawyerId());
			if (lawyer != null) {
				caseInfo.setStarLevel(4);
				lawyerCaseInfoRepository.save(caseInfo);
			} else {
				msg.setCode(MessageConstant.FAILED_CODE);
				msg.setMessage("找不到律师:" + caseInfo.getLawyerId());
			}
		} else {
			msg.setCode(MessageConstant.FAILED_CODE);
			msg.setMessage("lawyerId不能为空.");
		}

		return new ResponseEntity<>(msg, HttpStatus.OK);
	}

	@ApiOperation(httpMethod = "DELETE", value = "律师删除案例", notes = "律师添加经典案例")
	@RequestMapping(value = "/delete", method = RequestMethod.DELETE)
	public HttpEntity<?> delete(@RequestBody Long id) {
		Message msg = new Message();
		if (id != null) {
			lawyerCaseInfoRepository.delete(id);
		} else {
			msg.setCode(MessageConstant.FAILED_CODE);
			msg.setMessage("id不能为空.");
		}

		return new ResponseEntity<>(msg, HttpStatus.OK);
	}

	@ApiOperation(httpMethod = "GET", value = "律师电话咨询", notes = "律师电话咨询")
	@RequestMapping(value = "/myConsult", method = RequestMethod.GET)
	@ApiImplicitParams({ @ApiImplicitParam(name = "page", dataType = "integer", paramType = "query", value = "第几页"),
			@ApiImplicitParam(name = "size", dataType = "integer", paramType = "query", value = "分页条数") })
	public HttpEntity<?> myConsult(String lawyerId, String startDate, String endDate,
			@PageableDefault(page = 0, sort = { "createdDate" }, direction = Sort.Direction.DESC) Pageable pageable) {
		Message msg = new Message();
		if (StringUtils.isNotEmpty(lawyerId)) {
			// criteriaBuilder用于构建CriteriaQuery的构建器对象
			CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();

			// criteriaQuery包含查询语句的各个部分，如where、max、sum、groupBy、orderBy等
			CriteriaQuery<LawyerMicroInfo> criteriaQuery = criteriaBuilder.createQuery(LawyerMicroInfo.class);
			// 获取查询实例的属性，select * from User
			Root<LawyerMicroInfo> root = criteriaQuery.from(LawyerMicroInfo.class);
			//根据统计结果排序
			criteriaQuery.orderBy(criteriaBuilder.desc(root.get("createdDate")));
			
			// 查询条件
			List<Predicate> predicates = new ArrayList<>();
			// 日期（范围）
			if (StringUtils.isNotEmpty(startDate)) {
				Date begin = DateUtils.getDayBeginOrEndTime(startDate, "begin");

				predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createdDate"), begin));
			}
			if (StringUtils.isNotEmpty(endDate)) {
				Date end = DateUtils.getDayBeginOrEndTime(endDate, "end");

				predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("createdDate"), end));
			}

			predicates.add(criteriaBuilder.equal(root.get("lawyerId"), lawyerId));

			// 将所有条件用 and 联合起来
			if (!CollectionUtils.isEmpty(predicates)) {
				criteriaQuery.where(criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])));
			}

			List<LawyerMicroInfo> counts = entityManager.createQuery(criteriaQuery).getResultList();
			TypedQuery<LawyerMicroInfo> createQuery = entityManager.createQuery(criteriaQuery);
			createQuery.setFirstResult(pageable.getPageNumber() * pageable.getPageSize());
			createQuery.setMaxResults(pageable.getPageSize());

			Page page = new PageImpl<LawyerMicroInfo>(createQuery.getResultList(), pageable, counts.size());

			msg.setData(page);

		} else {
			msg.setCode(MessageConstant.FAILED_CODE);
			msg.setMessage("lawyerId不能为空");
		}
		return new ResponseEntity<>(msg, HttpStatus.OK);
	}

	@RequestMapping(value = "/homePagePic/{lawyerId}", method = RequestMethod.POST)
	@ApiOperation(httpMethod = "POST", value = "添加轮播图片", notes = "添加轮播图片")
	public HttpEntity<?> header(@PathVariable String lawyerId, @RequestBody List<String> homePicList) {
		Message msg = new Message();

		try {
			Lawyer lawyer = lawyerRepository.findOne(lawyerId);
			String homePagePic = Joiner.on(";").join(homePicList);
			lawyer.setHomePagePic(homePagePic);
			lawyerRepository.save(lawyer);

		} catch (Exception e) {
			msg.setCode(MessageConstant.FAILED_CODE);
			msg.setMessage(e.getMessage());
		}

		return new ResponseEntity<>(msg, HttpStatus.OK);
	}
	
	@RequestMapping(value = "/headerIco", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "修改律师头像", notes = "修改律师头像")
	public HttpEntity<?> headerIco(String lawyerId, String url) {
		Message msg = new Message();
		try {
			Lawyer lawyer = lawyerRepository.findOne(lawyerId);
			lawyer.setHeaderIco(url);
			lawyerRepository.save(lawyer);

		} catch (Exception e) {
			e.printStackTrace();
			msg.setCode(MessageConstant.FAILED_CODE);
			msg.setMessage(e.getMessage());
		}

		return new ResponseEntity<>(msg, HttpStatus.OK);
	}
	

	@ApiOperation(httpMethod = "GET", value = "我的主页", notes = "我的主页")
	@RequestMapping(value = "/myHome", method = RequestMethod.GET)
	public HttpEntity<?> myHome(String lawyerId) {
		Message msg = new Message();

		Lawyer lawyer = lawyerRepository.findOne(lawyerId);
		lawyer.setPassword(null);
		if (lawyer != null) {
			// 经典案例
			List<LawyerCaseInfo> list = lawyerCaseInfoRepository.findTop4ByLawyerIdOrderByStarLevelDesc(lawyerId);
			lawyer.setLawyerCaseInfos(list);
			msg.setData(lawyer);
		}

		return new ResponseEntity<>(msg, HttpStatus.OK);
	}

	@ApiOperation(httpMethod = "POST", value = "修改主页", notes = "修改主页")
	@RequestMapping(value = "/updateMyHome", method = RequestMethod.POST)
	public HttpEntity<?> updateMyHome(@RequestBody UpudateLawyerReq lawyerReq) {
		Message msg = new Message();
		
		Lawyer findLawyer = lawyerRepository.findOne(lawyerReq.getLawyerId());
		if (findLawyer != null) {
			BeanUtils.copyPropertiesIgnoreNullValue(lawyerReq, findLawyer,"starLevel","certification","workYear","doorPermissions","recommend");
			lawyerRepository.save(findLawyer);
		}
		return new ResponseEntity<>(msg, HttpStatus.OK);
	}
	

	@ApiOperation(httpMethod = "GET", value = "修改登陆状态", notes = "是否在线:0离线,1在线")
	@RequestMapping(value = "/updateLoginStatus", method = RequestMethod.GET)
	public HttpEntity<?> updateLoginStatus( String status,String lawyerId) {
		Message msg = new Message();

		Lawyer findLawyer = lawyerRepository.findOne(lawyerId);
		if (findLawyer != null) {
			findLawyer.setOnLine(status);
			lawyerRepository.save(findLawyer);
		}
		return new ResponseEntity<>(msg, HttpStatus.OK);
	}

	@ApiOperation(httpMethod = "POST", value = "律师修改个人信息", notes = "律师修改个人信息")
	@RequestMapping(value = "/update", method = RequestMethod.POST)
	public HttpEntity<?> update(String lawyerId, String nickName, String phone) {
		Message msg = new Message();

		Lawyer lawyer = lawyerRepository.findOne(lawyerId);
		if (lawyer != null) {
			lawyer.setNickName(nickName);
			lawyer.setPhone(phone);
			lawyerRepository.save(lawyer);
		} else {
			msg.setCode(MessageConstant.FAILED_CODE);
			msg.setMessage("没有找到该律师.");
		}
		return new ResponseEntity<>(msg, HttpStatus.OK);
	}
	@ApiOperation(httpMethod = "POST", value = "律师认证", notes = "律师认证")
	@RequestMapping(value = "/certification", method = RequestMethod.POST)
	public HttpEntity<?> certification(@RequestBody CertificationRequest certificationRequest) {
		Message msg = new Message();
		
		if (StringUtils.isEmpty(certificationRequest.getLicensedUrl())) {
			msg.setCode(MessageConstant.FAILED_CODE);
			msg.setMessage("请上传证件号");
			return new ResponseEntity<>(msg, HttpStatus.OK);
		}
		
		
		Lawyer lawyer = lawyerRepository.findOne(certificationRequest.getLawyerId());
		if (lawyer != null) {
			BeanUtils.copyPropertiesIgnoreNullValue(certificationRequest, lawyer,"starLevel","certification","workYear","doorPermissions","recommend");
			lawyer.setCertification(1);
			lawyerRepository.save(lawyer);
		} else {
			msg.setCode(MessageConstant.FAILED_CODE);
			msg.setMessage("没有找到该律师.");
		}
		return new ResponseEntity<>(msg, HttpStatus.OK);
	}

	
	@ApiOperation(httpMethod = "POST", value = "律师提现", notes = "律师提现")
	@RequestMapping(value = "/withdrawal", method = RequestMethod.POST)
	public HttpEntity<?> withdrawal(@RequestBody Withdrawal request) {
		Message msg = new Message();
		try {
			Lawyer lawyer = lawyerRepository.findOne(request.getUserId());
			if (lawyer != null) {
				
				if (request.getAmount() <100) {
					msg.setCode(MessageConstant.FAILED_CODE);
					msg.setMessage("提现最低金额100元");
					return new ResponseEntity<>(msg, HttpStatus.OK);
				}
				
				if (request.getAmount() > lawyer.getBalance()) {
					msg.setCode(MessageConstant.FAILED_CODE);
					msg.setMessage("超过可提现最大金额");
					return new ResponseEntity<>(msg, HttpStatus.OK);
				}
			
				lawyer.setBalance(lawyer.getBalance() - request.getAmount());
				lawyerRepository.save(lawyer);
				
				//保存提现表 
				request.setStauts(1);//提现中
				request.setNickName(lawyer.getNickName());
				request.setPhone(lawyer.getPhone());
				request.setHeaderIco(lawyer.getHeaderIco());
				request.setUserJob("律师");
				withdrawalRepository.save(request);
				
				// 保存变更记录
				MoneyFlows flow = new MoneyFlows();
				flow.setTypeFlow(2);
				flow.setUserId(request.getUserId());
				flow.setLawyerName(lawyer.getNickName());
				flow.setPhone(lawyer.getPhone());
				flow.setUserType("2");
				flow.setChangeMoney(0 - request.getAmount());
				flow.setDescription("提现");
				moneyFlowsRepository.save(flow);
			} else {
				msg.setCode(MessageConstant.FAILED_CODE);
				msg.setMessage("账号不存在");
			}

		} catch (Exception e) {
			e.printStackTrace();
			msg.setCode(MessageConstant.FAILED_CODE);
			msg.setMessage(MessageConstant.FAILED_MSG);
		}

		return new ResponseEntity<>(msg, HttpStatus.OK);
	}
}
